package com.moco.launcher.fragment;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.moco.launcher.R;
import com.moco.launcher.play.MocoPlayerClient;
import com.moco.launcher.view.HoloCircularProgressBar;
import com.mradar.sdk.record.DoresoListener;
import com.mradar.sdk.record.DoresoManager;
import com.mradar.sdk.record.DoresoMusicTrack;
import com.mradar.sdk.record.DoresoUtils;
import com.oazon.common.Logger;
import com.oazon.common.Assert;

public class MidomiFragment extends BaseFragment {
	private static final String TAG = "MidomiFragment";

	private static final String KEY = "fnYJhZhTcnrygamQfQX4Qu39kQnHmUfixGvEFT34X0I";
	private static final int FADE_OUT = 1;
	private static final int SHOW_PROGRESS = 2;

	private ImageView mImgViewBack = null;
	private ImageView mImgViewLight = null;
	private ImageView mImgViewProgress = null;
	private TextView mViewTop = null;
	private TextView mViewBottom = null;
	private TextView mViewVoiceResult = null;
	private HoloCircularProgressBar mProgressBar;
	private DoresoManager mDoresoManager;
	private boolean mIsProcessing = false;


	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		mDoresoManager = DoresoManager.getIntance(this.getContext(), KEY);
		mDoresoManager.setListener(new DoresoListener() {

			@Override
			public void onError(final int errorcode, String msg) {
				mDoresoManager.cancel();
				Logger.d(TAG, errorcode + ":" + msg);
				mIsProcessing = false;
			}

			@Override
			public void onFinish(DoresoMusicTrack[] tracks, String arg1) {
				Logger.d(TAG, "onfinish");
				mDoresoManager.stop();
				
				String result = "";
				int length = (tracks.length > 5) ? 5 : tracks.length;
				for (int i = 0; i < length; i++) {
					result += i + ":"
							+ getResources().getString(R.string.artist)
							+ tracks[i].getArtist() + "\n"
							+ getResources().getString(R.string.title)
							+ tracks[i].getName() + "\n" + "rate:"
							+ tracks[i].getRating() + "\n";
				}
				mViewVoiceResult.setText(result);
				
				mIsProcessing = false;
			}

			@Override
			public void onRecordEnd() {
				Logger.d(TAG, "onRecordEnd");
				mDoresoManager.stop();
				mIsProcessing = false;
				startRecognize();
			}

			@Override
			public void onRecording(byte[] buffer) {
				Logger.d(TAG, "onRecording");
				double volume = DoresoUtils.computeDb(buffer, buffer.length);
			}

		});
	}

	private File mSaveFile;

	public void start() {
		if (mIsProcessing) 
			return;
		
		mDoresoManager.start();
		mIsProcessing = true;
	}

	protected void stop() {
		if (mIsProcessing)
			mDoresoManager.stop();
	}

	protected void cancel() {
		if (!mIsProcessing) 
			return;
		
		mDoresoManager.cancel();
		mIsProcessing = false;
	}

	// TODO：是否考虑线程安全的？
	protected void startRecord() {
		if (mIsProcessing)
			return;
		
		File rootDir = Environment.getExternalStorageDirectory();
		Assert.notNull(rootDir);

		mSaveFile = new File(rootDir, "/mocoapp/" + System.currentTimeMillis() + ".pcm");

		try {
			if (!mSaveFile.exists())
				mSaveFile.createNewFile();
		} catch (IOException e) {
			e.printStackTrace();
		}

		mDoresoManager.startRecord();
		mIsProcessing = true;
	}

	protected void startRecognize() {
		if (mIsProcessing)
			return;
		
		File rootDir = Environment.getExternalStorageDirectory();
		Assert.notNull(rootDir);
		
		mSaveFile = new File(rootDir, "/mocoapp/" + System.currentTimeMillis() + ".pcm");
		if (!mSaveFile.exists())
			return;
		
		// FIXME: whole file put in buffer? maybe the file is very larger!
		byte[] buffer = new byte[(int) mSaveFile.length()];
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(mSaveFile);
			fis.read(buffer, 0, buffer.length);
			mDoresoManager.startRecognize(buffer);
			mIsProcessing = true;
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (fis != null)
					fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View rootView = inflater.inflate(R.layout.midomi_layout, container, false);
		
		mViewTop = (TextView) rootView.findViewById(R.id.top_text);
		mViewBottom = (TextView) rootView.findViewById(R.id.bottom_text);
		mViewVoiceResult = (TextView) rootView.findViewById(R.id.voice_result);
		mImgViewProgress = (ImageView) rootView.findViewById(R.id.progress);
		mImgViewLight = (ImageView) rootView.findViewById(R.id.midomi_light);
		mImgViewLight.setOnLongClickListener(new OnLongClickListener() {
			@Override
			public boolean onLongClick(View v) {
				actionStop();
				return false;
			}
		});

		mImgViewBack = (ImageView) rootView.findViewById(R.id.midomi);
		mImgViewBack.setOnLongClickListener(new OnLongClickListener() {
			@Override
			public boolean onLongClick(View v) {
				actionStart();
				return false;
			}
		});

		ImageView limageview = (ImageView) rootView.findViewById(R.id.icon_left);
		limageview.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				prevFragment();
			}
		});

		mProgressBar = (HoloCircularProgressBar) rootView.findViewById(R.id.holoCircularProgressBar);
		mProgressBar.setProgressColor(0xffee7b1d);
		mProgressBar.setProgressBackgroundColor(0x00000000);
		mProgressBar.setWheelSize(5);

		return rootView;
	}

	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			long pos;
			switch (msg.what) {
			case FADE_OUT:
				mProgressBar.setProgress(0);
				mHandler.removeMessages(SHOW_PROGRESS);
				break;
			case SHOW_PROGRESS:
				pos = setProgress();
				if (pos == 0)
					break;
				msg = obtainMessage(SHOW_PROGRESS);
				sendMessageDelayed(msg, 1000);
				break;
			}
		}
	};

	private void actionStart() {
		mImgViewBack.setVisibility(View.GONE);
		mImgViewLight.setVisibility(View.VISIBLE);
		MocoPlayerClient.getInstance().stop();
		updateProgress();
		start();
		startRecord();
	}

	private void actionStop() {
		mHandler.sendEmptyMessage(FADE_OUT);
		mPosition = 0;
		mViewTop.setVisibility(View.VISIBLE);
		mViewBottom.setVisibility(View.VISIBLE);
		mImgViewBack.setVisibility(View.VISIBLE);
		mImgViewLight.setVisibility(View.GONE);
		mImgViewProgress.setVisibility(View.GONE);
		stop();
	}

	private static long mPosition = 0;
	private static long duration = 1 * 60;

	private long setProgress() {
		mPosition++;
		if (mPosition == duration) {
			mPosition = 0;
			actionStop();
			return 0;
		}

		if (duration > 0) {
			long pos = mPosition * 360 / duration;
			float per = pos % 360;
			mProgressBar.setProgress(per);
		}

		int curPower = (int) (mPosition / 8);
		Logger.d(TAG, "curPower= " + curPower);
		switch (curPower) {
		case 0:
			mImgViewProgress.setImageResource(R.drawable.progress1);
			break;
		case 1:
			mImgViewProgress.setImageResource(R.drawable.progress2);
			break;
		case 2:
			mImgViewProgress.setImageResource(R.drawable.progress3);
			break;
		case 3:
			mImgViewProgress.setImageResource(R.drawable.progress4);
			break;
		case 4:
			mImgViewProgress.setImageResource(R.drawable.progress5);
			break;
		case 5:
			mImgViewProgress.setImageResource(R.drawable.progress6);
			break;
		case 6:
			mImgViewProgress.setImageResource(R.drawable.progress7);
			break;
		case 7:
			mImgViewProgress.setImageResource(R.drawable.progress8);
			break;
		default:
			break;
		}
		return mPosition;
	}

	public void updateProgress() {
		mImgViewProgress.setVisibility(View.VISIBLE);
		mViewTop.setVisibility(View.GONE);
		mViewBottom.setVisibility(View.GONE);
		mProgressBar.setProgress(0);
		mHandler.sendEmptyMessage(SHOW_PROGRESS);
	}
}
